/*----------------------------------------\ | Update the existing datasets; | |-------------------------------------------| |--------------------------------------------------------------------| |---------------------------| | Arguments: | | indata - input datasets, at least 2 datasets are required; | | by - key variables between the input datasets; | | this is the key variables we need for merging the | | datasets; | | Note: these variables will be used as the complex keys;| | keep - Keep the rows from which datasets; | | outdata - The output dataset; | |--------------------------------| |--------------------------------------------------------------------| |---------------------------------------| | Example: | | %update(indata=ridcrf.ae ridcrf.ae1, by=pt aedt docnum, keep=1, | | outdata=ae); | | Usgae: update(indata=,by=, keep=1, outdata=)/parmbuff; | \----------------------------------------*/ %macro update/parmbuff; /*--------------------------------------------\ | Copy Right: Duo Zhou; | | Created: 12-01-2002 1:54pm; | | Purpose: update existing datasets; | \--------------------------------------------*/ %local indata by keep outdata; %let _updatecnt_=0; %let syspbuff=%sysfunc(translate(%quote(%substr(%quote(%trim(%quote(%left(%quote(&syspbuff))))), 2, %eval(%length(%trim(%quote(%left(%quote(&syspbuff)))))-2))), %str(%'), %str(%"))); %let indata=; %let by=; %let keep=; %let outdata=; %do %while(%length(%nrbquote(%scan(%nrbquote(&syspbuff), %eval(&_updatecnt_+1), %nrbquote(,))))); %let _updatecnt_=%eval(&_updatecnt_+1); %let _udparam_=%nrbquote(%qscan(%nrbquote(&syspbuff), &_updatecnt_, %nrbquote(,))); %let _udparam1_=%trim(%left(%qscan(%nrbquote(&_udparam_), 1, %str(=)))); %let _udparam2_=%substr(%quote(&_udparam_), %eval(%index(%quote(&_udparam_),%str(=))+1), %eval(%length(&_udparam_)-%index(%quote(&_udparam_),%str(=)))); %if (not %index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&_udparam_))))), %str(=))) %then %do; %if (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&_udparam2_))))), %str(%()) eq 1) and (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(&_udparam2_))))))), %str(%))) eq 1) %then %let _udparam2_=%substr(%quote(%trim(%quote(%left(%quote(&_udparam2_))))), 2, %eval(%length(%trim(%quote(%left(%quote(&_udparam2_)))))-2)); %if (%quote(&_updatecnt_) = %quote(1)) %then %let indata=&_udparam2_; %else %if (%quote(&_updatecnt_) = %quote(2)) %then %let by=&_udparam2_; %else %if (%quote(&_updatecnt_) = %quote(3)) %then %do; %if (%scan(&_udparam2_,1,1234567890)=) %then %let keep=&_udparam2_; %else %let keep=; %end; %else %if (%quote(&_updatecnt_) = %quote(3)) %then %let outdata=&_udparam1_; %end; %else %if (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&_udparam2_))))), %str(%()) eq 1) and (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(&_udparam2_))))))), %str(%))) eq 1) %then %let &_udparam1_=%substr(%quote(%trim(%quote(%left(%quote(&_udparam2_))))), 2, %eval(%length(%trim(%quote(%left(%quote(&_udparam2_)))))-2)); %else %let &_udparam1_=&_udparam2_; %end; /* By Variables */ %if (%quote(&by)=) %then %do; %put ==> Alert! Merging Variables are not given!; %goto finish; %end; %let _updatebnt_=0; %let _updatesqlby_=; %do %while(%length(%nrbquote(%scan(%nrbquote(&by), %eval(&_updatebnt_+1), %nrbquote( ,))))); %let _updatebnt_=%eval(&_updatebnt_+1); %if (%quote(&_updatebnt_)=%quote(1)) %then %let _updatesqlby_=%nrbquote(%qscan(%nrbquote(&by), &_updatebnt_, %nrbquote( ,))); %else %let _updatesqlby_=%nrbquote(&_updatesqlby_), %nrbquote(%qscan(%nrbquote(&by), &_updatebnt_, %nrbquote( ,))); %end; /* Input Datasets */ %if (%quote(&indata)=) %then %do; %put ==> Alert! No Input dataset is provided!; %goto finish; %end; %else %if %index(&indata,.) = 0 %then %let indata=%upcase(work.&indata.); %else %let indata=%upcase(&indata); %let _updatednt_=0; %Let _updatenumdup_=0; %let _updatemergedata_=; %let _updatenvaliddata_=0; %do %while(%length(%nrbquote(%scan(%nrbquote(&indata), %eval(&_updatednt_+1), %nrbquote( ,))))); %let _updatednt_=%eval(&_updatednt_+1); %let _updatedata_&_updatednt_=%nrbquote(%qscan(%nrbquote(&indata), &_updatednt_, %nrbquote( ,))); %if (%sysfunc(exist(&&_updatedata_&_updatednt_))) or (%sysfunc(exist(&&_updatedata_&_updatednt_, VIEW))) %then %do; %let _updatenvaliddata_=%eval(&_updatenvaliddata_+1); options nonotes; proc sort data=&&_updatedata_&_updatednt_ out=_updatedata_&_updatednt_; by &by; run; options notes; %if (&_updatednt_ = 1) %then %do; %let _updatemergedata_=_updatedata_&_updatednt_ (in=in%trim(%left(&_updatednt_))); %put NOTE: There were %trim(%left(%nobs(_updatedata_&_updatednt_))) observations read from data set %trim(%left(%upcase(&&_updatedata_&_updatednt_))).; %end; %else %do; %let _updatemergedata_=&_updatemergedata_ _updatedata_&_updatednt_ (in=in%trim(%left(&_updatednt_))); %put NOTE: There were %trim(%left(%nobs(_updatedata_&_updatednt_))) observations read from data set %trim(%left(%upcase(&&_updatedata_&_updatednt_))).; %end; options nonotes; proc sql; create table _updatetmp_%trim(%left(&_updatednt_)) as select * from &&_updatedata_&_updatednt_ group by &_updatesqlby_ having count(*)>1; %if (%nobs(_updatetmp_%trim(%left(&_updatednt_)))) %then %Let _updatenumdup_=&_updatenumdup_+1; proc datasets library=work nolist; delete _updatetmp_%trim(%left(&_updatednt_)); run;quit; options notes; %end; %end; %if (&_updatenumdup_ >1) %then %do; %put ==> Alert! More than 1 dataset has duplicate records, this is many to many merge, update process failed!; %goto finish; %end; %if (&_updatednt_ < 2) %then %do; %put ==> Alert! Only 1 dataset is provided, dataset is not updated!; %goto finish; %end; %if (&_updatenvaliddata_ < 2) %then %do; %put ==> Alert! Only found 1 valid dataset, dataset is not updated!; %goto finish; %end; %if (%quote(&outdata) = ) %then %let outdata=&_updatedata_1; %else %if %index(&outdata,.) = 0 %then %let outdata=%upcase(work.&outdata.); %else %let outdata=%upcase(&outdata); %if (%quote(&keep) ne) %then %do; %if (&keep < 1) or (&keep > &_updatednt_) %then %do; %put ==> Alert! Only %trim(%left(&_updatednt_)) datasets are found, I cannot find the dataset %trim(%left(&keep)).; %goto finish; %end; %end; options nonotes; data &outdata; update &_updatemergedata_; by &by; %if (%quote(&keep) ne) %then if in%trim(%left(&keep));; run; proc sql; %do i=1 %to &_updatednt_; %if (%sysfunc(exist(_updatedata_&i))) %then drop table _updatedata_&i;; %end; quit; options notes; %put NOTE: There were %trim(%left(%nobs(&outdata))) observations write to data set %trim(%left(%upcase(&outdata))).; %finish: %mend update;